package com.gitee.easyopen.sdk;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.easyopen.sdk.resp.ErrorResp;
import com.gitee.easyopen.sdk.util.PostUtil;
import com.gitee.easyopen.sdk.util.SignUtil;

/**
 * 请求客户端，创建一个即可。
 * 
 * @author hc.tang
 *
 */
public class OpenClient {

    private static Logger logger = LoggerFactory.getLogger(OpenClient.class);
    private static final String UTF8 = "UTF-8";
    private static final String ZH_CN = "zh-CN";

    private String url;
    private String appKey;
    private String secret;
    private String lang = ZH_CN;

    private String appKeyName = "app_key";
    private String signName = "sign";
    private String dataName = "data";
    private String accessTokenName = "access_token";

    public OpenClient(String url, String appKey, String secret, String lang) {
        this(url, appKey, secret);
        this.lang = lang;
    }

    public OpenClient(String url, String appKey, String secret) {
        super();
        this.url = url;
        this.appKey = appKey;
        this.secret = secret;
    }
    
    public <T> T request(BaseReq request) {
        return request(request, null, null);
    }
    
    public <T> T request(BaseReq request,String accessToken) {
        return request(request, accessToken, null);
    }

    public <T> T request(BaseReq request,String accessToken, String jwt) {
        String json = JSON.toJSONString(request);
        JSONObject jsonObj = JSONObject.parseObject(json);
        if(accessToken != null) {
            jsonObj.put(accessTokenName, accessToken);
        }
        String data = jsonObj.getString(dataName);
        if (data == null || "".equals(data)) {
            data = "{}";
        }
        try {
            data = URLEncoder.encode(data, UTF8);
            jsonObj.put(dataName, data);
        } catch (UnsupportedEncodingException e) {
        }
        logger.debug("请求参数：{}", json);
        String body = this.post(url, jsonObj, jwt);
        T t = (T) JSON.parseObject(body, request.buildRespClass());
        return t;
    }
    
    public <T> T requestWithJwt(BaseReq request,String jwt) {
        return request(request, null, jwt);
    }

    /**
     * 发送请求
     * 
     * @param url
     *            请求连接
     * @param params
     *            请求参数
     * @return 服务端返回的内容
     */
    private String post(String url, JSONObject params, String jwt) {
        params.put(appKeyName, this.appKey);

        String sign = null;
        try {
            sign = SignUtil.buildSign(params, this.secret);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new SdkException("签名构建失败");
        }

        params.put(signName, sign);

        try {
            return PostUtil.post(url, params, lang, jwt);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            ErrorResp result = new ErrorResp();
            result.setCode("-1");
            result.setMsg(e.getMessage());
            return JSON.toJSONString(result);
        }
    }

    public String getLang() {
        return lang;
    }

    public void setLang(String lang) {
        this.lang = lang;
    }

}
